﻿using System.Collections.Generic;
using System.Linq;
using JBeamLibrary.Tools;
using JBeamLibrary.VehicleParts.Collections;
using JBeamLibrary.VehicleParts.Elements;
using JBeamLibrary.VehicleParts.Interfaces;

namespace JBeamLibrary.VehicleParts.Groups
{
    public class HubWheels : IVehicleGroup<HubWheel>
    {
        #region Fields

        private readonly Dictionary<int, bool> _enableTireSideSupportBeamsList = new Dictionary<int, bool>();
        private readonly Dictionary<int, bool> _selfCollisionList = new Dictionary<int, bool>();
        private readonly Dictionary<int, bool> _collisionList = new Dictionary<int, bool>();
        private readonly Dictionary<int, float> _radiusList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _wheelOffsetList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _tireWidthList = new Dictionary<int, float>();
        private readonly Dictionary<int, int> _numRaysList = new Dictionary<int, int>();
        private readonly Dictionary<int, long> _springExpansionList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _dampExpansionList = new Dictionary<int, long>();
        private readonly Dictionary<int, List<string>> _axleBeamsList = new Dictionary<int, List<string>>();
        private readonly Dictionary<int, int> _propulsedList = new Dictionary<int, int>();
        private readonly Dictionary<int, bool> _enableABSList = new Dictionary<int, bool>();
        private readonly Dictionary<int, int> _absThresholdList = new Dictionary<int, int>();
        private readonly Dictionary<int, float> _frictionCoefList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _nodeWeightList = new Dictionary<int, float>();
        private readonly Dictionary<int, NodeMaterial> _nodeMaterialList = new Dictionary<int, NodeMaterial>();
        private readonly Dictionary<int, long> _beamSpringList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _beamDampList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _beamDeformList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _beamStrengthList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _pressurePSIList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _maxPressurePSIList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _reinforcementPressurePSIList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _pressureSpringList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _reinforcementPressureSpringList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _pressureDampList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _reinforcementPressureDampList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _brakeTorqueList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _parkingTorqueList = new Dictionary<int, long>();
        private readonly Dictionary<int, float> _hubRadiusList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _hubWidthList = new Dictionary<int, float>();
        private readonly Dictionary<int, long> _hubBeamSpringList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _hubBeamDampList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _hubBeamDeformList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _hubBeamStrengthList = new Dictionary<int, long>();
        private readonly Dictionary<int, float> _hubNodeWeightList = new Dictionary<int, float>();
        private readonly Dictionary<int, NodeMaterial> _hubNodeMaterialList = new Dictionary<int, NodeMaterial>();
        private readonly Dictionary<int, float> _hubFrictionCoefList = new Dictionary<int, float>();
        private readonly Dictionary<int, long> _wheelTreadBeamSpringList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _wheelTreadBeamDampList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _wheelTreadBeamDeformList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _wheelTreadBeamStrengthList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _wheelPeripheryBeamSpringList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _wheelPeripheryBeamDampList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _wheelPeripheryBeamDeformList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _wheelPeripheryBeamStrengthList = new Dictionary<int, long>();
        private readonly Dictionary<int, bool> _enableHubcapsList = new Dictionary<int, bool>();
        private readonly Dictionary<int, bool> _hubcapSelfCollisionList = new Dictionary<int, bool>();
        private readonly Dictionary<int, bool> _hubcapCollisionList = new Dictionary<int, bool>();
        private readonly Dictionary<int, float> _hubcapWidthList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _hubcapOffsetList = new Dictionary<int, float>();
        private readonly Dictionary<int, long> _hubcapBeamSpringList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _hubcapBeamDampList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _hubcapBeamDeformList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _hubcapBeamStrengthList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _hubcapAttachBeamSpringList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _hubcapAttachBeamDampList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _hubcapAttachBeamDeformList = new Dictionary<int, long>();
        private readonly Dictionary<int, long> _hubcapAttachBeamStrengthList = new Dictionary<int, long>();
        private readonly Dictionary<int, float> _hubcapNodeWeightList = new Dictionary<int, float>();
        private readonly Dictionary<int, float> _hubcapCenterNodeWeightList = new Dictionary<int, float>();
        private readonly Dictionary<int, NodeMaterial> _hubcapNodeMaterialList = new Dictionary<int, NodeMaterial>();
        private readonly Dictionary<int, float> _hubcapFrictionCoefList = new Dictionary<int, float>();
        private readonly Dictionary<int, string> _hubcapGroupList = new Dictionary<int, string>();
        private readonly Dictionary<int, string> _hubcapBreakGroupList = new Dictionary<int, string>(); 
        private readonly HubWheelsCollection _collection = new HubWheelsCollection();

        #endregion

        #region Indexers

        /// <summary>Gets the hubWheel at the specified index</summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public HubWheel this[int index]
        {
            get
            {
                if (Collection.Count == 0)
                    return null;
                if (index < 0 || index >= Collection.Count)
                    return null;
                return Collection[index];
            }
        }

        /// <summary>Gets the hubWheel with the specified name</summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public HubWheel this[string name]
        {
            get { return Collection[name]; }
        }

        #endregion

        #region Properties

        public bool IsEmpty
        {
            get
            {
                return GroupHelper.GetPropertyLists(this).All(list => list.Count == 0) && Collection.Count == 0;
            }
        }

        public Dictionary<int, bool> EnableTireSideSupportBeamsList
        {
            get { return _enableTireSideSupportBeamsList; }
        }

        public Dictionary<int, float> RadiusList
        {
            get { return _radiusList; }
        }

        public Dictionary<int, float> HubRadiusList
        {
            get { return _hubRadiusList; }
        }

        public Dictionary<int, float> WheelOffsetList
        {
            get { return _wheelOffsetList; }
        }

        public Dictionary<int, float> HubWidthList
        {
            get { return _hubWidthList; }
        }

        public Dictionary<int, float> TireWidthList
        {
            get { return _tireWidthList; }
        }

        public Dictionary<int, int> NumRaysList
        {
            get { return _numRaysList; }
        }

        public Dictionary<int, long> BrakeTorqueList
        {
            get { return _brakeTorqueList; }
        }

        public Dictionary<int, long> ParkingTorqueList
        {
            get { return _parkingTorqueList; }
        }

        public Dictionary<int, long> HubBeamSpringList
        {
            get { return _hubBeamSpringList; }
        }

        public Dictionary<int, long> HubBeamDampList
        {
            get { return _hubBeamDampList; }
        }

        public Dictionary<int, long> BeamSpringList
        {
            get { return _beamSpringList; }
        }

        public Dictionary<int, long> BeamDampList
        {
            get { return _beamDampList; }
        }

        public Dictionary<int, long> HubBeamDeformList
        {
            get { return _hubBeamDeformList; }
        }

        public Dictionary<int, long> HubBeamStrengthList
        {
            get { return _hubBeamStrengthList; }
        }

        public Dictionary<int, long> BeamDeformList
        {
            get { return _beamDeformList; }
        }

        public Dictionary<int, long> BeamStrengthList
        {
            get { return _beamStrengthList; }
        }

        public Dictionary<int, float> HubNodeWeightList
        {
            get { return _hubNodeWeightList; }
        }

        public Dictionary<int, NodeMaterial> HubNodeMaterialList
        {
            get { return _hubNodeMaterialList; }
        }

        public Dictionary<int, float> HubFrictionCoefList
        {
            get { return _hubFrictionCoefList; }
        }

        public Dictionary<int, long> WheelTreadBeamSpringList
        {
            get { return _wheelTreadBeamSpringList; }
        }

        public Dictionary<int, long> WheelTreadBeamDampList
        {
            get { return _wheelTreadBeamDampList; }
        }

        public Dictionary<int, long> WheelTreadBeamDeformList
        {
            get { return _wheelTreadBeamDeformList; }
        }

        public Dictionary<int, long> WheelTreadBeamStrengthList
        {
            get { return _wheelTreadBeamStrengthList; }
        }

        public Dictionary<int, long> WheelPeripheryBeamSpringList
        {
            get { return _wheelPeripheryBeamSpringList; }
        }

        public Dictionary<int, long> WheelPeripheryBeamDampList
        {
            get { return _wheelPeripheryBeamDampList; }
        }

        public Dictionary<int, long> WheelPeripheryBeamDeformList
        {
            get { return _wheelPeripheryBeamDeformList; }
        }

        public Dictionary<int, long> WheelPeripheryBeamStrengthList
        {
            get { return _wheelPeripheryBeamStrengthList; }
        }

        public Dictionary<int, long> SpringExpansionList
        {
            get { return _springExpansionList; }
        }

        public Dictionary<int, long> DampExpansionList
        {
            get { return _dampExpansionList; }
        }

        public Dictionary<int, float> NodeWeightList
        {
            get { return _nodeWeightList; }
        }

        public Dictionary<int, NodeMaterial> NodeMaterialList
        {
            get { return _nodeMaterialList; }
        }

        public Dictionary<int, float> FrictionCoefList
        {
            get { return _frictionCoefList; }
        }

        public Dictionary<int, long> PressurePSIList
        {
            get { return _pressurePSIList; }
        }

        public Dictionary<int, long> MaxPressurePSIList
        {
            get { return _maxPressurePSIList; }
        }

        public Dictionary<int, long> ReinforcementPressurePSIList
        {
            get { return _reinforcementPressurePSIList; }
        }

        public Dictionary<int, long> PressureSpringList
        {
            get { return _pressureSpringList; }
        }

        public Dictionary<int, long> ReinforcementPressureSpringList
        {
            get { return _reinforcementPressureSpringList; }
        }

        public Dictionary<int, long> PressureDampList
        {
            get { return _pressureDampList; }
        }

        public Dictionary<int, long> ReinforcementPressureDampList
        {
            get { return _reinforcementPressureDampList; }
        }

        public Dictionary<int, bool> SelfCollisionList
        {
            get { return _selfCollisionList; }
        }

        public Dictionary<int, bool> CollisionList
        {
            get { return _collisionList; }
        }

        public Dictionary<int, bool> EnableHubcapsList
        {
            get { return _enableHubcapsList; }
        }

        public Dictionary<int, bool> HubcapSelfCollisionList
        {
            get { return _hubcapSelfCollisionList; }
        }

        public Dictionary<int, bool> HubcapCollisionList
        {
            get { return _hubcapCollisionList; }
        }

        public Dictionary<int, float> HubcapWidthList
        {
            get { return _hubcapWidthList; }
        }

        public Dictionary<int, float> HubcapOffsetList
        {
            get { return _hubcapOffsetList; }
        }

        public Dictionary<int, long> HubcapBeamSpringList
        {
            get { return _hubcapBeamSpringList; }
        }

        public Dictionary<int, long> HubcapBeamDampList
        {
            get { return _hubcapBeamDampList; }
        }

        public Dictionary<int, long> HubcapBeamDeformList
        {
            get { return _hubcapBeamDeformList; }
        }

        public Dictionary<int, long> HubcapBeamStrengthList
        {
            get { return _hubcapBeamStrengthList; }
        }

        public Dictionary<int, long> HubcapAttachBeamSpringList
        {
            get { return _hubcapAttachBeamSpringList; }
        }

        public Dictionary<int, long> HubcapAttachBeamDampList
        {
            get { return _hubcapAttachBeamDampList; }
        }

        public Dictionary<int, long> HubcapAttachBeamDeformList
        {
            get { return _hubcapAttachBeamDeformList; }
        }

        public Dictionary<int, long> HubcapAttachBeamStrengthList
        {
            get { return _hubcapAttachBeamStrengthList; }
        }

        public Dictionary<int, float> HubcapNodeWeightList
        {
            get { return _hubcapNodeWeightList; }
        }

        public Dictionary<int, float> HubcapCenterNodeWeightList
        {
            get { return _hubcapCenterNodeWeightList; }
        }

        public Dictionary<int, NodeMaterial> HubcapNodeMaterialList
        {
            get { return _hubcapNodeMaterialList; }
        }

        public Dictionary<int, float> HubcapFrictionCoefList
        {
            get { return _hubcapFrictionCoefList; }
        }

        public Dictionary<int, string> HubcapGroupList
        {
            get { return _hubcapGroupList; }
        }

        public Dictionary<int, string> HubcapBreakGroupList
        {
            get { return _hubcapBreakGroupList; }
        }

        public Dictionary<int, List<string>> AxleBeamsList
        {
            get { return _axleBeamsList; }
        }

        public Dictionary<int, int> PropulsedList
        {
            get { return _propulsedList; }
        }

        public Dictionary<int, bool> EnableABSList
        {
            get { return _enableABSList; }
        }

        public Dictionary<int, int> ABSThresholdList
        {
            get { return _absThresholdList; }
        }

        public HubWheelsCollection Collection
        {
            get { return _collection; }
        }

        public IVehicleGroupCollection<HubWheel> GroupCollection
        {
            get { return Collection; }
        }

        public int Count
        {
            get { return Collection.Count; }
        }

        #endregion

        #region Methods

        public void SetElementValue(int index, string propName, object value)
        {
            var elem = Collection[index];
            var prop = elem.GetType().GetProperty(propName);
            prop.SetValue(elem, value);
        }

        public object GetElementValue(int index, string propName)
        {
            var elem = Collection[index];
            var prop = elem.GetType().GetProperty(propName);
            return prop.GetValue(elem);
        }

        public IEnumerable<KeyValuePair<string, object>> GetElementValues(int index)
        {
            var elem = Collection[index];
            var props = elem.GetType().GetProperties();
            return props.Select(prop => new KeyValuePair<string, object>(prop.Name, prop.GetValue(elem))).AsEnumerable();
        }

        #endregion
    }
}
